package com.ruoyi.ghxx.util;

import org.apache.commons.codec.binary.Hex;
import org.springframework.web.multipart.MultipartFile;
import javax.imageio.ImageIO;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.*;
/**
 * @author jxj
 * 定义文字加水印
 */
public class ImageWatermarkUtils {
    private final static String[] IMAGE_TYPE = {"PNG","JPEG","JPG", "BMP", "GIF"};
    private final static int HEADER_SIZE = 4;
    /**
     * 水印字体
     */
    private static final Font FONT = new Font("微软雅黑", Font.PLAIN, 12);
    /**
     * 透明度
     */
    private static final AlphaComposite COMPOSITE = AlphaComposite
            .getInstance(AlphaComposite.SRC_OVER, 0.8f);

    /**
     * 水印之间的间隔
     */
    private static final int X_MOVE = 150;

    /**
     * 水印之间的间隔
     */
    private static final int Y_MOVE = 200;

    /**
     * 打水印(文字)
     *
     * @param file       MultipartFile
     * @return MultipartFile
     */
    public static MultipartFile markWithContent(MultipartFile file,String keyword) {

        FileOutputStream fos = null;
        try {
            String fileType = getFileType(file.getInputStream());
            boolean isImage = matchImageType(fileType);
            if(!isImage){
                System.out.println("文件类型非图片类型，支持：png、jpeg、jpg、bmp、gif，当前文件类型：" + fileType);
                return file;
            }
            BufferedImage srcImg = ImageIO.read(file.getInputStream());

            // 图片宽、高
            int imgWidth = srcImg.getWidth();
            int imgHeight = srcImg.getHeight();

            // 图片缓存
            BufferedImage bufImg = new BufferedImage(imgWidth, imgHeight, BufferedImage.TYPE_INT_RGB);

            // 创建绘图工具
            Graphics2D graphics = bufImg.createGraphics();
            // 设置水印颜色
            graphics.setColor(Color.white);
            graphics.fillRect(0, 0, imgWidth, imgHeight);
            // 画入原始图像
            graphics.drawImage(srcImg, 0, 0, imgWidth, imgHeight, null);
            // 设置水印透明度
            graphics.setComposite(COMPOSITE);
            // 设置倾斜角度
            graphics.rotate(Math.toRadians(-35), (double) bufImg.getWidth() / 2,
                    (double) bufImg.getHeight() / 2);

            // 设置水印字体
            graphics.setColor(Color.gray);
            graphics.setFont(FONT);
            // 消除java.awt.Font字体的锯齿
            graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

            int xCoordinate = -imgWidth / 2, yCoordinate;
            String mark = "ls65535";
            // 字体长度
            int markWidth = FONT.getSize() * getTextLength(mark);
            // 字体高度
            int markHeight = FONT.getSize();

            double odf = 1.5 ;
            // 循环添加水印
            while (xCoordinate < imgWidth * odf) {
                yCoordinate = -imgHeight / 2;
                while (yCoordinate < imgHeight * odf) {
                    graphics.drawString(keyword, xCoordinate, yCoordinate);
                    yCoordinate += markHeight + Y_MOVE;
                }
                xCoordinate += markWidth + X_MOVE;
            }
            InputStream inputStream = buffToInputStream(bufImg);
            // 释放画图工具
            graphics.dispose();
            return new MultipartFileDto(file.getName(),file.getOriginalFilename(),file.getContentType(),inputStream);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (fos != null) {
                try {
                    fos.flush();
                    fos.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

    /**
     * 计算水印文本长度
     * 1、中文长度即文本长度 2、英文长度为文本长度二分之一
     * @param text
     * @return
     */
    public static int getTextLength(String text) {
        //水印文字长度
        int length = text.length();

        for (int i = 0; i < text.length(); i++) {
            String s = String.valueOf(text.charAt(i));
            if (s.getBytes().length > 1) {
                length++;
            }
        }
        length = length % 2 == 0 ? length / 2 : length / 2 + 1;
        return length;
    }

    public static InputStream buffToInputStream(BufferedImage buffer) throws IOException {
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        ImageIO.write(buffer, "png", os);
        return new ByteArrayInputStream(os.toByteArray());
    }
    private static boolean matchImageType(String fileType){
        if(null == fileType || fileType.isEmpty()){
            return false;
        }

        for (String type : IMAGE_TYPE) {
            if (fileType.equalsIgnoreCase(type)) {
                return true;
            }
        }

        return false;
    }
    private static String getFileType(InputStream is){
        String fileType = null;
        String fileHeader;
        byte[] temp = new byte[HEADER_SIZE];

        try {
            is.read(temp, 0, HEADER_SIZE);
            // 将读取到的字节数组转为十六进制字符串,，方法来自apache的commons-codec包
            fileHeader = Hex.encodeHexString(temp).toUpperCase();

            // 以下罗列几种类型，更多自行拓展
            if (fileHeader.contains("504B0304")) {

                fileType = "xlsx";
            } else if (fileHeader.contains("FFD8FF")) {

                fileType = "jpg";
            } else if (fileHeader.contains("89504E47")) {

                fileType = "png";
            } else if (fileHeader.contains("47494638")) {

                fileType = "gif";
            } else if (fileHeader.contains("25504446")) {

                fileType = "pdf";
            } else if (fileHeader.contains("424D")) {

                fileType = "bmp";
            }else if(fileHeader.contains("3C3F786D")) {
                fileType = "svg";
            }else {
                fileType = "未知类型";
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return fileType;
    }
}
